// File Item.cpp
//
// Purpose: Contains the struct for an item in the game
//
// Author : Bryson King (edited)
// Original Code Provided by: Mat Buckland 2002 (fup@ai-junkie.com)
// Date : 21 March 2013
// --------------------------------------------------------------
#define DEBUG_SECTION

#include "Item.h"

#include <string>

using namespace std;

SItem::SItem()
{
	ID = NextID();
	Name = "";
	DamageDonePerAttack = 0;
	AmmoInWeapon = 0;
	ProjectileWeapon = false;
	ItemVisibleToPlayer = true;
}

int SItem::NextID()
{
	static int iNextID = 0;
	return iNextID++;
}

CItems::CItems() : m_iNumberOfItemsInList(0), m_iNumberOfWeaponsInList(0)
{
	m_pHeadOfList = new item_node();
	m_pHeadOfList->next = nullptr;
	m_pTailOfList = m_pHeadOfList;
}

CItems::~CItems()
{
	item_node* tempNode;

	// Cycle through each node deleting each until the list is empty 
	while (m_pHeadOfList != nullptr)
	{
		tempNode = m_pHeadOfList;
		m_pHeadOfList = m_pHeadOfList->next;
		delete tempNode;
	}
}

void CItems::AddItem(SItem* item)
{
	// Create the new node for the list
	item_node* newNode = new item_node();
	newNode->item = item;
	newNode->next = nullptr;

	// Add the node to the list
	m_pTailOfList->next = newNode;
	m_pTailOfList = newNode;

	m_iNumberOfItemsInList++;

	// If it's a weapon, add to weapons count
	if (item->DamageDonePerAttack > 0)
		m_iNumberOfWeaponsInList++;
}

SItem* CItems::RetrieveItem(string name)
{
	item_node* tempNode = m_pHeadOfList->next;
	SItem* returnItem = nullptr;

	// Search the list for the node to delete
	while (tempNode != nullptr)
	{
		// If the node is found, remove the node and delete it
		if (tempNode->item->Name == name)
		{
			returnItem = tempNode->item;
			break;
		}

		// Go to next item in the list
		tempNode = tempNode->next;
	}

	return returnItem;
}

SItem* CItems::RetrieveItem(int index)
{
	item_node* tempNode = m_pHeadOfList;

	// If the index is invalid, return a nullptr
	if (index >= m_iNumberOfItemsInList)
		return nullptr;

	// Search the list for the node to return
	for (int i = 0; i <= index; i++)
	{
			tempNode = tempNode->next;
	}

	return tempNode->item;
}

SItem** CItems::RetrieveAllItems(int& count)
{
	SItem** returnItems = new SItem*[NumberOfItems()];
	item_node* tempNode = m_pHeadOfList->next;
	int iterator = 0;

	// Add each item to the array
	while (tempNode != nullptr)
	{
		returnItems[iterator++] = (tempNode->item);
		tempNode = tempNode->next;
	}

	count = iterator;
	return returnItems;
}

SItem** CItems::RetrieveAllWeapons(int& count)
{
	SItem** returnItems = new SItem*[NumberOfItems()];
	item_node* tempNode = m_pHeadOfList->next;
	int iterator = 0;

	// Add each item to the array
	while (tempNode != nullptr)
	{
		// If it's a weapon, add it to the list
		if (tempNode->item->DamageDonePerAttack > 0)
			returnItems[iterator++] = (tempNode->item);
		tempNode = tempNode->next;
	}

	count = iterator;
	return returnItems;
}

string CItems::ListItems()
{
	string sReturnValue = "";
	item_node* tempNode = m_pHeadOfList->next;

	// Loop through the list, writing item information to a string
	while (tempNode != nullptr)
	{
		sReturnValue += tempNode->item->Name;
		sReturnValue += "\n";
		sReturnValue += "Damage Per Attack: ";
		sReturnValue += to_string(tempNode->item->DamageDonePerAttack);
		sReturnValue += "\n";
		if (tempNode->item->ProjectileWeapon)
		{
			sReturnValue += "Ammunition: ";
			sReturnValue += to_string(tempNode->item->AmmoInWeapon);
			sReturnValue += "\n";
		}
		sReturnValue += "\n";
		tempNode = tempNode->next;
	}

	return sReturnValue;
}

SItem* CItems::RemoveItem(SItem* item)
{
	int iItemID = item->ID;
	item_node* tempNode = m_pHeadOfList;
	item_node* entityNode;
	SItem* returnItem = nullptr;

	// Search the list for the node to delete
	while (tempNode->next != nullptr)
	{
		// If the node is found, remove the node and delete it
		if (tempNode->next->item->ID == iItemID)
		{
			entityNode = tempNode->next;
			tempNode->next = tempNode->next->next;
			entityNode->next = nullptr;
			returnItem = entityNode->item;
			delete entityNode;
			break;
		}

		// Advance through the list
		tempNode = tempNode->next;
	}

	m_iNumberOfItemsInList--;

	// If it's a weapon, decrement the weapon count
	if (item->DamageDonePerAttack > 0)
		m_iNumberOfWeaponsInList--;

	return returnItem;
}

int CItems::NumberOfItems()
{
	return m_iNumberOfItemsInList;
}
